﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.ServiceModel.Syndication;
using Kkc.Application.Helpers;
using Kkc.Application.Specifications;
using Kkc.Model;
using Kkc.Common;

namespace Kkc.Application.Controllers
{
    public class AnnouncementController : Controller
    {
        public ActionResult Index(int? pageIndex, int? pageSize)
        {
            return View();
        }

        public ActionResult List(int? pageIndex, int? pageSize)
        {
            var take = pageSize ?? 10;
            var skip = take * pageIndex ?? 0;

            using (var entities = new KkcDataEntities())
            {
                IQueryable<Announcement> query = entities.Announcements;

                var specification = IocContainer.Current.Resolve<ISpecification<Announcement>>("published");
                query = query.Satisfy(specification);

                query = query.OrderByDescending(a => a.CreationDate);

                var list = query.Skip(skip).Take(take).ToList();

                ViewData.Model = list;
            }

            return View();
        }

        public ActionResult Feed(string format, int? pageIndex, int? pageSize)
        {
            if (!new[] { "rss", "atom" }.Contains(format))
                throw new ArgumentOutOfRangeException("format", format, "Format must be one of the allowed values. \"rss\" or \"atom\".");

            var take = pageSize ?? 10;
            var skip = take * pageIndex ?? 0;

            SyndicationFeed syndicationFeed;
            using (var entities = new KkcDataEntities())
            {
                IQueryable<Announcement> query = entities.Announcements;

                var specification = IocContainer.Current.Resolve<ISpecification<Announcement>>("published");
                query = query.Satisfy(specification);

                query = query.OrderByDescending(a => a.CreationDate);

                var syndicationItems = new List<SyndicationItem>();
                foreach (var queryItem in query.Skip(skip).Take(take))
                {
                    var syndicationItem = new SyndicationItem();
                    syndicationItem.Title = TextSyndicationContent.CreateHtmlContent(queryItem.Title);
                    syndicationItem.Summary = TextSyndicationContent.CreateHtmlContent(queryItem.Summary);
                    syndicationItem.PublishDate = new DateTimeOffset(queryItem.CreationDate);
                    syndicationItem.LastUpdatedTime = new DateTimeOffset(queryItem.ModificationDate);
                    syndicationItem.Id = "/Announcement/feed/" + format + "/" + queryItem.Id;
                    syndicationItem.Content = TextSyndicationContent.CreateHtmlContent(queryItem.Body);
                    syndicationItem.Categories.Add(new SyndicationCategory("Nyheter"));
                    syndicationItem.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(Url.Action("details", new { id = queryItem.Id }), UriKind.Relative), "text/html"));
                    syndicationItems.Add(syndicationItem);
                }

                syndicationFeed = new SyndicationFeed(syndicationItems);
                syndicationFeed.Title = TextSyndicationContent.CreatePlaintextContent("Kristiansand Karate Club - Siste nytt");
                syndicationFeed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(Url.Action("index", new { pageIndex = (pageIndex ?? 0), pageSize = pageSize } ), UriKind.Relative)));
                syndicationFeed.Links.Add(SyndicationLink.CreateSelfLink(new Uri(Url.Action("feed", new { pageIndex = (pageIndex ?? 0), pageSize = pageSize }), UriKind.Relative)));
                if (pageIndex > 0)
                {
                    var previous = new SyndicationLink();
                    previous.Uri = new Uri(Url.Action("feed", new { format = format, pageIndex = (pageIndex - 1), pageSize = pageSize }), UriKind.Relative);
                    previous.RelationshipType = "Previous";
                    syndicationFeed.Links.Add(previous);
                }

                if (skip + take < query.Count())
                {
                    var next = new SyndicationLink();
                    next.Uri = new Uri(Url.Action("feed", new { format = format, pageIndex = (pageIndex + 1), pageSize = pageSize }), UriKind.Relative);
                    next.RelationshipType = "Next";
                    syndicationFeed.Links.Add(next);
                }
                syndicationFeed.LastUpdatedTime = new DateTimeOffset(query.OrderByDescending(a => a.ModificationDate).Select(a => a.ModificationDate).First());
                syndicationFeed.Language = "nb-NO";
                syndicationFeed.Id = "/Announcement/Feed/"+format;
                syndicationFeed.Generator = "KKC Web Application";
                syndicationFeed.Description = TextSyndicationContent.CreatePlaintextContent("Denne samlingen innholder siste nytt fra klubben.");
                syndicationFeed.Copyright = TextSyndicationContent.CreateHtmlContent("Kristiansand Karate Club &copy; "+ DateTime.Now.Year);
                syndicationFeed.Categories.Add(new SyndicationCategory("Nyheter"));
            }

            if (string.Equals("rss", format, StringComparison.OrdinalIgnoreCase))
                return new SyndicationFeedResult(new Rss20FeedFormatter(syndicationFeed));

            return new SyndicationFeedResult(new Atom10FeedFormatter(syndicationFeed));
        }

        public ActionResult Details(int id)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Announcements
                            where a.Id == id
                            select a;

                var announcement = query.FirstOrDefault();
                ViewData.Model = announcement;
            }

            return View();
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Edit(int id)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Announcements
                            where a.Id == id
                            select a;

                var announcement = query.FirstOrDefault();
                ViewData.Model = announcement;
            }

            return View();
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, string title, string summary, string body, string link, DateTime? expirationDate)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Announcements
                            where a.Id == id
                            select a;

                var announcement = query.First();
                announcement.Title = title;
                announcement.Summary = summary;
                announcement.Body = body;
                announcement.Link = link;
                announcement.ExpirationDate = expirationDate;
                entities.SaveChanges();
            }

            return RedirectToAction("Details", new { Id = id });
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Create()
        {
            return View();
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(string title, string summary, string body, string link, DateTime? expirationDate)
        {
            using (var entities = new KkcDataEntities())
            {
                var announcement = new Announcement();
                announcement.Title = title;
                announcement.Summary = summary;
                announcement.Body = body;
                announcement.Link = link;
                announcement.ExpirationDate = expirationDate;
                entities.AddToAnnouncements(announcement);
                entities.SaveChanges();
                entities.Refresh(System.Data.Objects.RefreshMode.StoreWins, announcement);
                return RedirectToAction("Details", new { Id = announcement.Id });
            }

        }
    }
}
